package com.yisoo.ubag.iot.manager;


import com.alibaba.fastjson.JSONObject;
import com.yisoo.common.constant.RedisStringConstant;
import com.yisoo.ubag.iot.constant.AmqpEnum;
import com.yisoo.ubag.iot.entity.MsgBackEntity;
import com.yisoo.ubag.iot.entity.StatusEntity;
import com.yisoo.ubag.iot.service.DeviceService;
import com.yisoo.ubag.iot.vo.AckMqttContentVo;
import com.yisoo.ubag.iot.vo.DeviceStatusMqttContentVo;
import com.yisoo.common.vo.OnlineVo;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.jms.Message;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service("amqpManager")
public class AmqpManager {

    @Autowired
    public StringRedisTemplate stringRedisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    DeviceService deviceService;

    public void runProcessor(MsgBackEntity msgBackEntity) {
        //如果getCommand拿不到数据，就将topic后缀当做command
//    MsgBackEntity(messageId=1367766339875351552, mTopic=/a19pJ9fEVwE/1ec8_bag/user/pub/status, mContent={msg:"heart",code:200,gps:"",bat:6.598389,hum:47.0,tem:22.3,stu:1,nbao:0,wbao:0}, productKey=null, deviceName=null, direction=null, other=null, command=null)
        switch (msgBackEntity.getCommand()){
            case STATUS_CHANGE://状态改变
                runStatusChange(msgBackEntity);
                break;
            case PUB_STATUS://发布消息
                runPubStatus(msgBackEntity);
                break;
            case PUB_ACK://发布消息
                runPubAck(msgBackEntity);
                break;
            default:
                System.out.println(">>>>>>"+msgBackEntity);
                break;
        }
    }
    private void runPubAck(MsgBackEntity msgBackEntity){
        AckMqttContentVo ackMqttContentVo = JSONObject.parseObject(msgBackEntity.getMContent(), AckMqttContentVo.class);
        ackMqttContentVo.setDeviceName(msgBackEntity.getDeviceName());
        ackMqttContentVo.setProductKey(msgBackEntity.getProductKey());

        switch(ackMqttContentVo.getMsgCode()){
            case 0:
                //live心跳包
                //心跳包不做处理，维持通信
//                System.out.println("心跳包："+ackMqttContentVo);
                break;
            case 1:
                //存储箱汇报绑定的背包
                System.out.println("绑定包："+ackMqttContentVo);
                //处理vo中的数据
                ackMqttContentVo.setMsg(ackMqttContentVo.getMsg().substring(1));
                //递交给消息队列处理
                String tempKey  = RedisStringConstant.BIND_BOX_AND_BAG+ackMqttContentVo.getDeviceName();
                stringRedisTemplate.opsForValue().set(tempKey,JSONObject.toJSONString(ackMqttContentVo),RedisStringConstant.ONLINE_HEART_TIME, TimeUnit.SECONDS);

                rabbitTemplate.convertAndSend("ubag.exchange.pub","mqtt.pub",ackMqttContentVo,new CorrelationData(UUID.randomUUID().toString()));
            default:
                System.out.println("数据类型未知"+ackMqttContentVo);
        }

    }
    private void runPubStatus(MsgBackEntity msgBackEntity) {

        StatusEntity statusEntity = new StatusEntity(msgBackEntity);
        // 状态改变需要的操作：
        String key = RedisStringConstant.DEV_PUB_STATUS + statusEntity.getDeviceName();
        stringRedisTemplate.opsForValue().set(key,JSONObject.toJSONString(statusEntity));

        OnlineVo onlineVo = new OnlineVo();
        onlineVo.setDevId(deviceService.getDevByName(statusEntity.getDeviceName()).getDevId());
        onlineVo.setDeviceStatus("ONLINE");
        onlineVo.setProductKey(statusEntity.getProductKey());
        onlineVo.setDeviceName(statusEntity.getDeviceName());
        String tempKey;
        //redis维护一个在线设备名单
        if(statusEntity.getDeviceName().contains("bag")){
             tempKey = RedisStringConstant.ONLINE_BAG + onlineVo.getDevId();
        }else{
            tempKey = RedisStringConstant.ONLINE_BOX + onlineVo.getDevId();
        }
        stringRedisTemplate.opsForValue().set(tempKey,JSONObject.toJSONString(onlineVo),RedisStringConstant.ONLINE_HEART_TIME, TimeUnit.SECONDS);

        rabbitTemplate.convertAndSend("ubag.exchange.pub","mqtt.pub",statusEntity,new CorrelationData(UUID.randomUUID().toString()));
    }

    private void runStatusChange(MsgBackEntity msgBackEntity) {
        //存入缓存，给APP服务使用
        //存入消息队列，持久化到数据库
        String content = msgBackEntity.getMContent();
        //在状态改变消息中的content数据抽象到VO
        DeviceStatusMqttContentVo deviceStatusMqttContentVo = JSONObject.parseObject(content, DeviceStatusMqttContentVo.class);
        String key = RedisStringConstant.DEV_STATUS_OBJECT + deviceStatusMqttContentVo.getDeviceName();
        //存入缓存
        stringRedisTemplate.opsForValue().set(key,JSONObject.toJSONString(deviceStatusMqttContentVo));
        //存入消息队列
        rabbitTemplate.convertAndSend("ubag.exchange.pub","mqtt.pub",deviceStatusMqttContentVo,new CorrelationData(UUID.randomUUID().toString()));
    }

    public MsgBackEntity parseAmqpDataToMsgBackEntity(Message message) throws Exception{

        byte[] body = message.getBody(byte[].class);
        String content = new String(body);

        //topic原语
        String topic = message.getStringProperty("topic");
        String messageId = message.getStringProperty("messageId");

        //从topic中解析出product devname
        String[] strs = topic.split("/");
        String productKey = null;
        String deviceName = null;
        String direction = null;
        String other = null;
        AmqpEnum command = null;
        if (strs.length == 5) {//  /a184GvZNZRz/1db2_bag/user/update
            //含user 的就是自定义的
            if (strs[3].equals("user")){
                productKey = strs[1];
                deviceName = strs[2];
            }
        }else if(strs.length == 6){  // /as/mqtt/status/a184GvZNZRz/1db2_bag,
            //状态改变消息
            if (strs[1].equals("as") && strs[2].equals("mqtt") && strs[3].equals("status")){
                productKey = strs[4];
                deviceName = strs[5];
                direction = "in";//消息进入服务器
                command = AmqpEnum.STATUS_CHANGE;
            }
            //
            if (strs[3].equals("user")){
                productKey = strs[1];
                deviceName = strs[2];
                if(strs[5].equals("order")){
                    direction = "in";//消息进入服务器
                    command = AmqpEnum.SUB_ORDER;
                }else if(strs[5].equals("resp")){
                    direction = "in";//消息进入服务器
                    command = AmqpEnum.SUB_RESP;
                }else if(strs[5].equals("status")){
                    direction = "in";//消息进入服务器
                    command = AmqpEnum.PUB_STATUS;
                }else if(strs[5].equals("ack")){
                    direction = "in";//消息进入服务器
                    command = AmqpEnum.PUB_ACK;
                }

                //    String SubOrder = "sub/order";//服务器命令帧
//    String SubResp = "sub/resp";//服务器回复帧
//    String PubStatus = "pub/status"; //设备汇报帧
//    String PubAck = "pub/ack"; //设备确认帧
            }
        }
        return new MsgBackEntity(messageId,topic,content,productKey,deviceName,direction,other,command);
    }

//topic = /as/mqtt/status/a184GvZNZRz/1db2_bag,
// messageId = 1360147881650145280,
// content = {"lastTime":"2021-02-12 16:44:59.948","utcLastTime":"2021-02-12T08:44:59.948Z","clientIp":"221.15.25.66","utcTime":"2021-02-12T08:44:59.968Z","time":"2021-02-12 16:44:59.968","productKey":"a184GvZNZRz","deviceName":"1db2_bag","status":"online"}
//topic = /a184GvZNZRz/1db2_bag/user/update,
// messageId = 1360147917242900480,
// content = 123
//topic = /as/mqtt/status/a184GvZNZRz/1db2_bag,
// messageId = 1360147935706327552,
// content = {"lastTime":"2021-02-12 16:45:12.850","utcLastTime":"2021-02-12T08:45:12.850Z","clientIp":"221.15.25.66","utcTime":"2021-02-12T08:45:12.856Z","time":"2021-02-12 16:45:12.856","productKey":"a184GvZNZRz","deviceName":"1db2_bag","status":"offline"}


}
